Visaptverošs ceļvedis React aplikāciju veiktspējas optimizācijai, izmantojot useMemo, useCallback un React.memo. Uzziniet, kā novērst nevajadzīgus atkārtotus renderējumus un uzlabot lietotāju pieredzi.
React Veiktspējas Optimizācija: useMemo, useCallback un React.memo Meistarība
React, populāra JavaScript bibliotēka lietotāja saskarņu veidošanai, ir pazīstama ar savu uz komponentiem balstīto arhitektūru un deklaratīvo stilu. Tomēr, aplikācijām kļūstot sarežģītākām, veiktspēja var kļūt par problēmu. Nevajadzīgi komponentu atkārtoti renderējumi var novest pie lēnas veiktspējas un sliktas lietotāju pieredzes. Par laimi, React piedāvā vairākus rīkus veiktspējas optimizācijai, tostarp useMemo
, useCallback
un React.memo
. Šis ceļvedis iedziļinās šajās tehnikās, sniedzot praktiskus piemērus un noderīgus padomus, lai palīdzētu jums izveidot augstas veiktspējas React aplikācijas.
Izpratne par React Atkārtotiem Renderējumiem
Pirms iedziļināties optimizācijas tehnikās, ir svarīgi saprast, kāpēc React notiek atkārtoti renderējumi. Kad komponenta stāvoklis vai rekvizīti mainās, React aktivizē šī komponenta un, iespējams, tā bērnu komponentu atkārtotu renderēšanu. React izmanto virtuālo DOM, lai efektīvi atjauninātu faktisko DOM, bet pārmērīgi atkārtoti renderējumi joprojām var ietekmēt veiktspēju, īpaši sarežģītās aplikācijās. Iedomājieties globālu e-komercijas platformu, kurā produktu cenas tiek bieži atjauninātas. Bez optimizācijas pat nelielas cenas izmaiņas varētu izraisīt atkārtotus renderējumus visā produktu sarakstā, ietekmējot lietotāju pārlūkošanu.
Kāpēc Komponenti Tiek Atkārtoti Renderēti
- Stāvokļa Izmaiņas: Kad komponenta stāvoklis tiek atjaunināts, izmantojot
useState
vaiuseReducer
, React atkārtoti renderē komponentu. - Rekvizītu Izmaiņas: Ja komponents saņem jaunus rekvizītus no sava vecākkomponenta, tas tiks atkārtoti renderēts.
- Vecākkomponenta Atkārtoti Renderējumi: Kad vecākkomponents tiek atkārtoti renderēts, tā bērnu komponenti arī tiks atkārtoti renderēti pēc noklusējuma, neatkarīgi no tā, vai to rekvizīti ir mainījušies.
- Konteksta Izmaiņas: Komponenti, kas patērē React Kontekstu, tiks atkārtoti renderēti, kad mainīsies konteksta vērtība.
Veiktspējas optimizācijas mērķis ir novērst nevajadzīgus atkārtotus renderējumus, nodrošinot, ka komponenti tiek atjaunināti tikai tad, kad to dati ir faktiski mainījušies. Apsveriet scenāriju, kas ietver reāllaika datu vizualizāciju akciju tirgus analīzei. Ja diagrammu komponenti tiek atkārtoti renderēti nevajadzīgi ar katru nelielu datu atjauninājumu, aplikācija kļūs nereaģējoša. Atkārtotu renderējumu optimizācija nodrošinās vienmērīgu un atsaucīgu lietotāju pieredzi.
Iepazīstinām ar useMemo: Dārgu Aprēķinu Memoizācija
useMemo
ir React hook, kas memoizē aprēķina rezultātu. Memoizācija ir optimizācijas tehnika, kas saglabā dārgu funkciju izsaukumu rezultātus un atkārtoti izmanto šos rezultātus, kad atkal parādās tās pašas ievades. Tas novērš nepieciešamību atkārtoti izpildīt funkciju nevajadzīgi.
Kad Lietot useMemo
- Dārgi Aprēķini: Kad komponentam ir jāveic aprēķinu ziņā intensīvs aprēķins, pamatojoties uz tā rekvizītiem vai stāvokli.
- Atsauču Vienlīdzība: Kad vērtība tiek nodota kā rekvizīts bērnu komponentam, kas paļaujas uz atsauču vienlīdzību, lai noteiktu, vai atkārtoti renderēt.
Kā Darbojas useMemo
useMemo
pieņem divus argumentus:
- Funkcija, kas veic aprēķinu.
- Atkarību masīvs.
Funkcija tiek izpildīta tikai tad, kad mainās viena no atkarībām masīvā. Pretējā gadījumā useMemo
atgriež iepriekš memoizēto vērtību.
Piemērs: Fibonači Virknes Aprēķināšana
Fibonači virkne ir klasisks aprēķinu ziņā intensīva aprēķina piemērs. Izveidosim komponentu, kas aprēķina n-to Fibonači skaitli, izmantojot useMemo
.
import React, { useState, useMemo } from 'react';
function Fibonacci({ n }) {
const fibonacciNumber = useMemo(() => {
console.log('Calculating Fibonacci...'); // Demonstrates when the calculation runs
function calculateFibonacci(num) {
if (num <= 1) {
return num;
}
return calculateFibonacci(num - 1) + calculateFibonacci(num - 2);
}
return calculateFibonacci(n);
}, [n]);
return Fibonacci({n}) = {fibonacciNumber}
;
}
function App() {
const [number, setNumber] = useState(5);
return (
setNumber(parseInt(e.target.value))}
/>
);
}
export default App;
Šajā piemērā funkcija calculateFibonacci
tiek izpildīta tikai tad, kad mainās rekvizīts n
. Bez useMemo
funkcija tiktu izpildīta katrā Fibonacci
komponenta atkārtotā renderējumā, pat ja n
paliktu nemainīgs. Iedomājieties, ka šis aprēķins notiek globālā finanšu informācijas panelī - katrs tirgus pulss izraisa pilnīgu pārrēķinu, kas izraisa ievērojamu kavēšanos. useMemo
to novērš.
Iepazīstinām ar useCallback: Funkciju Memoizācija
useCallback
ir vēl viens React hook, kas memoizē funkcijas. Tas novērš jaunas funkcijas instances izveidi katrā renderējumā, kas var būt īpaši noderīgi, nododot atzvanus kā rekvizītus bērnu komponentiem.
Kad Lietot useCallback
- Atzvanu Nodošana kā Rekvizīti: Nododot funkciju kā rekvizītu bērnu komponentam, kas izmanto
React.memo
vaishouldComponentUpdate
, lai optimizētu atkārtotus renderējumus. - Notikumu Apstrādātāji: Definējot notikumu apstrādātāju funkcijas komponentā, lai novērstu nevajadzīgus bērnu komponentu atkārtotus renderējumus.
Kā Darbojas useCallback
useCallback
pieņem divus argumentus:
- Funkcija, kas jāmemoizē.
- Atkarību masīvs.
Funkcija tiek atkārtoti izveidota tikai tad, kad mainās viena no atkarībām masīvā. Pretējā gadījumā useCallback
atgriež to pašu funkcijas instanci.
Piemērs: Pogas Klikšķa Apstrāde
Izveidosim komponentu ar pogu, kas aktivizē atzvana funkciju. Mēs izmantosim useCallback
, lai memoizētu atzvana funkciju.
import React, { useState, useCallback } from 'react';
function Button({ onClick, children }) {
console.log('Button re-rendered'); // Demonstrates when the Button re-renders
return ;
}
const MemoizedButton = React.memo(Button);
function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Button clicked');
setCount((prevCount) => prevCount + 1);
}, []); // Empty dependency array means the function is only created once
return (
Count: {count}
Increment
);
}
export default App;
Šajā piemērā funkcija handleClick
tiek izveidota tikai vienreiz, jo atkarību masīvs ir tukšs. Kad App
komponents tiek atkārtoti renderēts count
stāvokļa izmaiņu dēļ, funkcija handleClick
paliek nemainīga. Komponents MemoizedButton
, kas ietīts ar React.memo
, tiks atkārtoti renderēts tikai tad, ja mainīsies tā rekvizīti. Tā kā rekvizīts onClick
(handleClick
) paliek nemainīgs, komponents Button
netiek atkārtoti renderēts nevajadzīgi. Iedomājieties interaktīvu karšu aplikāciju. Katru reizi, kad lietotājs mijiedarbojas, var tikt ietekmēti desmitiem pogu komponentu. Bez useCallback
šīs pogas tiktu atkārtoti renderētas nevajadzīgi, radot lēnu pieredzi. Izmantojot useCallback
, tiek nodrošināta vienmērīgāka mijiedarbība.
Iepazīstinām ar React.memo: Komponentu Memoizācija
React.memo
ir augstākas kārtas komponents (HOC), kas memoizē funkcionālo komponentu. Tas novērš komponenta atkārtotu renderēšanu, ja tā rekvizīti nav mainījušies. Tas ir līdzīgs PureComponent
klases komponentiem.
Kad Lietot React.memo
- Tīri Komponenti: Kad komponenta izvade ir atkarīga tikai no tā rekvizītiem un tam nav sava stāvokļa.
- Dārga Renderēšana: Kad komponenta renderēšanas process ir aprēķinu ziņā dārgs.
- Bieži Atkārtoti Renderējumi: Kad komponents tiek bieži atkārtoti renderēts, pat ja tā rekvizīti nav mainījušies.
Kā Darbojas React.memo
React.memo
ietīts funkcionālā komponentā un seklīgi salīdzina iepriekšējos un nākamos rekvizītus. Ja rekvizīti ir vienādi, komponents netiks atkārtoti renderēts.
Piemērs: Lietotāja Profila Attēlošana
Izveidosim komponentu, kas attēlo lietotāja profilu. Mēs izmantosim React.memo
, lai novērstu nevajadzīgus atkārtotus renderējumus, ja lietotāja dati nav mainījušies.
import React from 'react';
function UserProfile({ user }) {
console.log('UserProfile re-rendered'); // Demonstrates when the component re-renders
return (
Name: {user.name}
Email: {user.email}
);
}
const MemoizedUserProfile = React.memo(UserProfile, (prevProps, nextProps) => {
// Custom comparison function (optional)
return prevProps.user.id === nextProps.user.id; // Only re-render if the user ID changes
});
function App() {
const [user, setUser] = React.useState({
id: 1,
name: 'John Doe',
email: 'john.doe@example.com',
});
const updateUser = () => {
setUser({ ...user, name: 'Jane Doe' }); // Changing the name
};
return (
);
}
export default App;
Šajā piemērā komponents MemoizedUserProfile
tiks atkārtoti renderēts tikai tad, ja mainīsies rekvizīts user.id
. Pat ja mainīsies citi user
objekta rekvizīti (piemēram, vārds vai e-pasts), komponents netiks atkārtoti renderēts, ja vien ID nebūs atšķirīgs. Šī pielāgotā salīdzināšanas funkcija React.memo
nodrošina detalizētu kontroli pār to, kad komponents tiek atkārtoti renderēts. Apsveriet sociālo mediju platformu ar pastāvīgi atjauninātiem lietotāju profiliem. Bez React.memo
lietotāja statusa vai profila attēla maiņa izraisītu pilnīgu profila komponenta atkārtotu renderēšanu, pat ja galvenā lietotāja informācija paliktu nemainīga. React.memo
ļauj veikt mērķtiecīgus atjauninājumus un ievērojami uzlabo veiktspēju.
useMemo, useCallback un React.memo Kombinēšana
Šīs trīs tehnikas ir visefektīvākās, ja tās tiek izmantotas kopā. useMemo
memoizē dārgus aprēķinus, useCallback
memoizē funkcijas un React.memo
memoizē komponentus. Apvienojot šīs tehnikas, jūs varat ievērojami samazināt nevajadzīgu atkārtotu renderējumu skaitu savā React aplikācijā.
Piemērs: Sarežģīts Komponents
Izveidosim sarežģītāku komponentu, kas parāda, kā apvienot šīs tehnikas.
import React, { useState, useCallback, useMemo } from 'react';
function ListItem({ item, onUpdate, onDelete }) {
console.log(`ListItem ${item.id} re-rendered`); // Demonstrates when the component re-renders
return (
{item.text}
);
}
const MemoizedListItem = React.memo(ListItem);
function List({ items, onUpdate, onDelete }) {
console.log('List re-rendered'); // Demonstrates when the component re-renders
return (
{items.map((item) => (
))}
);
}
const MemoizedList = React.memo(List);
function App() {
const [items, setItems] = useState([
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' },
]);
const handleUpdate = useCallback((id) => {
setItems((prevItems) =>
prevItems.map((item) =>
item.id === id ? { ...item, text: `Updated ${item.text}` } : item
)
);
}, []);
const handleDelete = useCallback((id) => {
setItems((prevItems) => prevItems.filter((item) => item.id !== id));
}, []);
const memoizedItems = useMemo(() => items, [items]);
return (
);
}
export default App;
Šajā piemērā:
useCallback
tiek izmantots, lai memoizētu funkcijashandleUpdate
unhandleDelete
, novēršot to atkārtotu izveidi katrā renderējumā.useMemo
tiek izmantots, lai memoizētu masīvuitems
, novēršot komponentaList
atkārtotu renderēšanu, ja masīva atsauce nav mainījusies.React.memo
tiek izmantots, lai memoizētu komponentusListItem
unList
, novēršot to atkārtotu renderēšanu, ja to rekvizīti nav mainījušies.
Šī tehniku kombinācija nodrošina, ka komponenti tiek atkārtoti renderēti tikai tad, kad tas ir nepieciešams, kas ievērojami uzlabo veiktspēju. Iedomājieties liela mēroga projektu pārvaldības rīku, kurā uzdevumu saraksti tiek pastāvīgi atjaunināti, dzēsti un pārkārtoti. Bez šīm optimizācijām jebkura neliela izmaiņa uzdevumu sarakstā izraisītu kaskādi atkārtotu renderējumu, padarot aplikāciju lēnu un nereaģējošu. Stratēģiski izmantojot useMemo
, useCallback
un React.memo
, aplikācija var saglabāt veiktspēju pat ar sarežģītiem datiem un biežiem atjauninājumiem.
Papildu Optimizācijas Tehnikas
Lai gan useMemo
, useCallback
un React.memo
ir jaudīgi rīki, tie nav vienīgās iespējas React veiktspējas optimizācijai. Šeit ir dažas papildu tehnikas, kas jāapsver:
- Koda Sadalīšana: Sadaliet savu aplikāciju mazākos blokos, kurus var ielādēt pēc pieprasījuma. Tas samazina sākotnējo ielādes laiku un uzlabo kopējo veiktspēju.
- Slinka Ielāde: Ielādējiet komponentus un resursus tikai tad, kad tie ir nepieciešami. Tas var būt īpaši noderīgi attēliem un citiem lieliem resursiem.
- Virtualizācija: Renderējiet tikai redzamo lielā saraksta vai tabulas daļu. Tas var ievērojami uzlabot veiktspēju, strādājot ar lieliem datu kopumiem. Bibliotēkas, piemēram,
react-window
unreact-virtualized
, var palīdzēt ar to. - Debouncing un Throttling: Ierobežojiet funkciju izpildes ātrumu. Tas var būt noderīgi, apstrādājot tādus notikumus kā ritināšana un izmēru maiņa.
- Nemaināmība: Izmantojiet nemaināmas datu struktūras, lai izvairītos no nejaušām mutācijām un vienkāršotu izmaiņu noteikšanu.
Globāli Apsvērumi Optimizācijai
Optimizējot React aplikācijas globālai auditorijai, ir svarīgi ņemt vērā tādus faktorus kā tīkla latentums, ierīču iespējas un lokalizācija. Šeit ir daži padomi:
- Satura Piegādes Tīkli (CDN): Izmantojiet CDN, lai apkalpotu statiskos resursus no vietām, kas ir tuvāk jūsu lietotājiem. Tas samazina tīkla latentumu un uzlabo ielādes laiku.
- Attēlu Optimizācija: Optimizējiet attēlus dažādiem ekrāna izmēriem un izšķirtspējām. Izmantojiet saspiešanas paņēmienus, lai samazinātu failu izmērus.
- Lokalizācija: Ielādējiet tikai nepieciešamos valodas resursus katram lietotājam. Tas samazina sākotnējo ielādes laiku un uzlabo lietotāju pieredzi.
- Adaptīvā Ielāde: Nosakiet lietotāja tīkla savienojumu un ierīces iespējas un attiecīgi pielāgojiet aplikācijas darbību. Piemēram, jūs varat atspējot animācijas vai samazināt attēla kvalitāti lietotājiem ar lēniem tīkla savienojumiem vai vecākām ierīcēm.
Secinājums
React aplikācijas veiktspējas optimizācija ir būtiska, lai nodrošinātu vienmērīgu un atsaucīgu lietotāju pieredzi. Apgūstot tādas tehnikas kā useMemo
, useCallback
un React.memo
, un apsverot globālās optimizācijas stratēģijas, jūs varat izveidot augstas veiktspējas React aplikācijas, kas atbilst dažādu lietotāju bāzes vajadzībām. Atcerieties profilēt savu aplikāciju, lai identificētu veiktspējas vājās vietas, un stratēģiski izmantojiet šīs optimizācijas tehnikas. Neoptimizējiet priekšlaicīgi – koncentrējieties uz jomām, kurās varat panākt visnozīmīgāko ietekmi.
Šis ceļvedis sniedz stabilu pamatu React veiktspējas optimizāciju izpratnei un ieviešanai. Turpinot izstrādāt React aplikācijas, atcerieties prioritizēt veiktspēju un pastāvīgi meklēt jaunus veidus, kā uzlabot lietotāju pieredzi.